﻿using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CRM.Extensions;
using CRM.Models;
using CRM.Models.Email;
using CRM.ViewModels.Email;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace CRM.Controllers.Email
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmailSendHistoryController : BaseController
    {
        private readonly MyDbContext _dbContext;
        private readonly UserManager<User> _userManager;

        public EmailSendHistoryController(MyDbContext dbContext, UserManager<User> userManager)
        {
            _dbContext = dbContext;
            _userManager = userManager;
        }

        [HttpPost(nameof(Index))]
        public async Task<ResultStruct> Index(EmailSendHistoryListQuery query)
        {
            var user = await _userManager.GetUserAsync(User);
            var result =
                await _dbContext.EmailSendHistory
                    .Where(m => m.OemId == user.OemId && m.CompanyId == user.CompanyId && m.GroupId == user.GroupId &&
                                m.UserId == user.Id)
                    .WhenWhere(!string.IsNullOrEmpty(query.MarketingTaskName),
                        m => m.MarketingTaskName.StartsWith(query.MarketingTaskName) ||
                             m.MarketingTaskName.EndsWith(query.MarketingTaskName))
                    .WhenWhere(query.State.IsNotNull(), m => m.State == query.State)
                    .WhenWhere(query.Flag > 0, m => (m.Details & query.Flag) == query.Flag)
                    .WhenWhere(query.NegativeFlag > 0, m => (~m.Details & query.NegativeFlag) == query.NegativeFlag)
                    .WhenWhere(query.SendingType != 0 && query.SendingType != null,
                        m => m.SendingType == query.SendingType)
                    // .WhenWhere(query.EmailPlatform != null, m => m.EmailPlatform == query.EmailPlatform)
                    .WhenWhere(query.CreatedAt != null && query.CreatedAt.Length == 2,
                        m => m.CreatedAt >= query.CreatedAt[0] && m.CreatedAt <= query.CreatedAt[1].AddDays(1))
                    .OrderByDescending(m => m.Id)
                    .ToPaginateAsync(query.Page, query.Limit);

            // result = result.Transform(m =>
            // {
            //     // 免费发送暂时无法看到打开记录
            //     if (m.SendingType == EmailSendHistory.SendingTypeEnum.Free)
            //         m.Details &= ~(int)DetailsEnum.Open;
            //     return m;
            // });
            return Success(result);
        }

        [HttpPost(nameof(SendingFree))]
        public async Task<ResultStruct> SendingFree(EmailSendHistoryListQuery query)
        {
            return await Index(query);
        }

        [HttpPost("[action]")]
        public async Task<ResultStruct> SendingFreeCreate(EmailSendHistoryVM vm)
        {
            var user = await _userManager.GetUserAsync(User);
            if (!ModelState.IsValid) return Error(message: ModelState.ToString());
            var model = vm.NewModel(_dbContext, user);
            await _dbContext.EmailSendHistory.AddAsync(model);
            await _dbContext.SaveChangesAsync();

            var emailMarket = await _dbContext.EmailMarketing
                .Where(m => m.OemId == user.OemId && m.CompanyId == user.CompanyId && m.GroupId == user.GroupId &&
                            m.UserId == user.Id)
                .Where(m => m.Id == model.Source).FirstOrDefaultAsync();

            if (emailMarket.State == EmailMarketing.StateEnum.UnSubmit)
                emailMarket.SetState(EmailMarketing.StateEnum.Submitted);

            var sendNum = await _dbContext.EmailSendHistory.Where(e => e.Source == emailMarket.Id)
                .Select(e => e.ReceiverEmail).Distinct().CountAsync();
            if (sendNum >= emailMarket.SubmitNum)
                emailMarket.SetState(EmailMarketing.StateEnum.Completed);

            // 发送成功时, 将发送成功数量+1
            if (model.State)
            {
                _dbContext.Entry(emailMarket).Increment(m => m.SendingNum, 1);

                var emailConfig = await _dbContext.EmailConfig
                    .Where(m => m.OemId == user.OemId && m.CompanyId == user.CompanyId && m.GroupId == user.GroupId &&
                                m.UserId == user.Id)
                    .Where(e => e.EmailAddress == model.SenderEmail)
                    .FirstOrDefaultAsync();

                if (emailConfig is not null)
                {
                    emailConfig.LatestSendTime = DateTime.Now;
                    var last24Hours = DateTime.Today;
                    var lastDaySendNum = await _dbContext.EmailSendHistory
                        .Where(m => m.OemId == user.OemId && m.CompanyId == user.CompanyId &&
                                    m.GroupId == user.GroupId &&
                                    m.UserId == user.Id)
                        .Where(e => e.SenderEmail == model.SenderEmail && e.CreatedAt >= last24Hours)
                        .CountAsync();
                    emailConfig.LastDaySendNum = lastDaySendNum;
                }
            }

            await _dbContext.SaveChangesAsync();
            return Success(new { IsCompleted = emailMarket.State == EmailMarketing.StateEnum.Completed });
        }

        [HttpPost(nameof(SendingByServer))]
        public async Task<ResultStruct> SendingByServer(EmailSendHistoryListQuery query)
        {
            return await Index(query);
        }

        [HttpPost(nameof(Create))]
        public async Task<ResultStruct> Create(EmailSendHistoryVM vm)
        {
            var user = await _userManager.GetUserAsync(User);
            if (!ModelState.IsValid) return Error(message: ModelState.ToString());
            var model = vm.NewModel(_dbContext, user);
            await _dbContext.EmailSendHistory.AddAsync(model);
            await _dbContext.SaveChangesAsync();
            return Success();
        }

        [HttpGet(nameof(Info))]
        public async Task<ResultStruct> Info([FromQuery] int id)
        {
            var user = await _userManager.GetUserAsync(User);
            var result = await _dbContext.EmailSendHistory
                .Where(m => m.OemId == user.OemId && m.CompanyId == user.CompanyId && m.GroupId == user.GroupId &&
                            m.UserId == user.Id)
                .Where(m => m.Id == id)
                .FirstAsync();
            return Success(result);
        }

        [HttpGet(nameof(EmailMarketingHistory))]
        public async Task<ResultStruct> EmailMarketingHistory([FromQuery] int id)
        {
            var user = await _userManager.GetUserAsync(User);
            var result = await _dbContext.EmailSendHistory
                .Where(m => m.OemId == user.OemId && m.CompanyId == user.CompanyId && m.GroupId == user.GroupId &&
                            m.UserId == user.Id)
                .Where(m => m.Source == id)
                .ToArrayAsync();
            return Success(result);
        }

#nullable enable
        [Route("[action]")]
        public async Task<ResultStruct> GetDetailsByMessageId([FromQuery] long messageId, string? eventType)
        {
            var result = await _dbContext.WebhookEventDetails.Where(m => m.MessageId == messageId)
                .WhenWhere(eventType.IsNotNull(), m => m.Event == eventType).ToArrayAsync();
            return Success(result);
        }

#nullable restore

        [HttpGet("[action]")]
        public async Task<IActionResult> Download(string ids, bool all = false)
        {
            var user = await _userManager.GetUserAsync(User);
            var root = _dbContext.EmailSendHistory
                .Where(m => m.OemId == user.OemId && m.CompanyId == user.CompanyId && m.GroupId == user.GroupId &&
                            m.UserId == user.Id);
            if (!all)
            {
                var idsArr = ids.Split(",").Select(id => int.TryParse(id, out var v) ? v : -1).ToArray();
                root = root.Where(m => idsArr.Contains(m.Id));
            }
            
            var results = await root.ToListAsync();

            var sb = new StringBuilder();
            // 添加表头
            sb.Append("客户信息,客户邮箱,发送邮箱,发送时间,发送状态,是否打开,是否退订\n");
            foreach (var history in results)
            {
                sb.Append($"{Helper.FormatCsvField(history.Name)},{Helper.FormatCsvField(history.ReceiverEmail)}," +
                          $"{Helper.FormatCsvField(history.SenderEmail)},{history.CreatedAt.ToString("yyyy-MM-dd HH:mm:ss")}," +
                          $"{(history.State ? "成功" : "失败")},{(history.IsOpen ? "是" : "否")},{(history.IsUnsub ? "是" : "否")}\n");
            }

            return File(Encoding.UTF8.GetBytes(sb.ToString()), "application/octet-stream", "发送历史.csv");
        }
        
        
    }
}